package com.file.system.controller.system;


import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.file.system.entity.res.CommonResult;
import com.file.system.entity.res.DataPage;
import com.file.system.entity.system.WebTask;
import com.file.system.plugin.task.ScheduledConfig;
import com.file.system.service.system.IWebTaskService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.support.CronExpression;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.validation.constraints.Max;
import javax.validation.constraints.Min;
import java.util.List;

import static cn.hutool.core.util.ObjectUtil.isNotEmpty;
import static com.file.system.tools.Formater.isValidJavaClass;


/**
 * 定时任务
 *
 * @author jch
 */
@RestController
@Validated
@RequestMapping("/web/task")
public class WebTaskController {

    @Autowired
    private IWebTaskService service;
    @Autowired
    private ScheduledConfig scheduledConfig;

    /**
     * 查询定时任务分页
     *
     * @param pageIndex 页数
     * @param pageSize  每页条数
     * @return CommonResult
     * @apiNote -
     * @author jch
     */
    @PostMapping("/page/{pageIndex}/{pageSize}")
    public CommonResult<DataPage<List<WebTask>>> select(@PathVariable
                                                        @Min(value = 1, message = "页数最小1")
                                                        Integer pageIndex,
                                                        @PathVariable
                                                        @Min(value = 1, message = "每页条数最小1")
                                                        @Max(value = 100, message = "每页条数最大100")
                                                        Integer pageSize,
                                                        @RequestBody @Validated WebTask webTask
    ) {
        QueryWrapper<WebTask> query = new QueryWrapper<>();
        query.orderByDesc("a.id");
        //查询状态为未删除的数据
        query.eq("a.is_del", 0);
        //查询任务名称
        query.like(isNotEmpty(webTask.getName()), "a.name", webTask.getName());
        //查询定时时间
        query.like(isNotEmpty(webTask.getCron()), "a.cron", webTask.getCron());
        //查询任务类名
        query.like(isNotEmpty(webTask.getClassName()), "a.class_name", webTask.getClassName());
        //查询字典组
        query.eq(isNotEmpty(webTask.getDictGroup()), "a.dict_group", webTask.getDictGroup());
        //查询字典任务开始
        query.eq(isNotEmpty(webTask.getDictTaskStart()), "a.dict_task_start", webTask.getDictTaskStart());
        //查询字典开启状态
        query.eq(isNotEmpty(webTask.getDictOnOff()), "a.dict_on_off", webTask.getDictOnOff());
        //查询集合
        DataPage<List<WebTask>> dp = service.page(pageIndex, pageSize, query);
        return CommonResult.ok().setResult(dp);
    }


    /**
     * 通过id查询定时任务
     *
     * @param id 定时任务id
     * @return CommonResult
     * @apiNote -
     * @author jch
     */
    @PostMapping("/id/{id}")
    public CommonResult<WebTask> selectById(@PathVariable
                                            @Min(value = 1, message = "id长度最小1")
                                            Long id) {
        //查询集合
        WebTask webTask = service.getById(id);
        return CommonResult.ok().setResult(webTask);
    }


    /**
     * 通过ids查询定时任务集合
     *
     * @return CommonResult
     * @apiNote -
     * @author jch
     */
    @PostMapping("/listByIds")
    public CommonResult<List<WebTask>> listByIds(@RequestBody List<Long> ids) {
        //查询集合
        List<WebTask> list = service.listByIds(ids);
        return CommonResult.ok().setResult(list);
    }


    /**
     * 查询所有非删除状态定时任务
     *
     * @return CommonResult
     * @apiNote -
     * @author jch
     */
    @PostMapping("/listAll")
    public CommonResult<List<WebTask>> listAll() {
        //查询集合
        List<WebTask> list = service.listAll();
        return CommonResult.ok().setResult(list);
    }


    /**
     * 通过id删除定时任务
     *
     * @param id id
     * @return CommonResult
     * @apiNote -
     * @author jch
     */
    @PostMapping("/remove/{id}")
    public CommonResult del(@PathVariable
                            @Min(value = 1, message = "id长度最小1")
                            Long id) {
        //停止该任务id的定时任务
        Boolean flag = scheduledConfig.stop(id);
        //返回
        return CommonResult.check(service.removeById(id));
    }


    /**
     * 通过id编辑定时任务
     *
     * @param webTask 定时任务
     * @return CommonResult
     * @apiNote -
     * @author jch
     */
    @PostMapping("/updateById")
    public CommonResult<WebTask> updateById(@RequestBody @Validated(WebTask.update.class) WebTask webTask) {
        //校验cron表达式是否正确
        if (!CronExpression.isValidExpression(webTask.getCron())) {
            return CommonResult.fail().setText("cron表达式错误");
        }
        try {
            //检查java类是否存在
            Class.forName(webTask.getClassName());
        } catch (ClassNotFoundException e) {
            return CommonResult.fail().setText("java类不存在");
        }
        //编辑修改
        boolean state = service.updateById(webTask);
        return CommonResult.check(state).setResult(webTask);
    }


    /**
     * 添加定时任务
     *
     * @param webTask 定时任务
     * @return CommonResult
     * @apiNote -
     * @author jch
     */
    @PostMapping("/save")
    public CommonResult<WebTask> save(@RequestBody @Validated(WebTask.add.class) WebTask webTask) {
        //检查cron表达式是否正确
        if (!CronExpression.isValidExpression(webTask.getCron())) {
            return CommonResult.fail().setText("cron表达式错误");
        }
        //检查Java类是否存在
        if (!isValidJavaClass(webTask.getClassName())) {
            return CommonResult.fail().setText("Java类不存在");
        }
        //添加定时任务
        boolean state = service.save(webTask);
        return CommonResult.check(state).setResult(webTask);
    }


    /**
     * 启动定时任务
     *
     * @param id 定时任务id
     * @return CommonResult
     * @apiNote -
     * @author jch
     */
    @PostMapping("/start/{id}")
    public CommonResult start(@PathVariable
                              @Min(value = 1, message = "id长度最小1")
                              Long id) {
        Boolean flag = scheduledConfig.start(id);
        if (!flag) return CommonResult.fail();
        return CommonResult.ok();
    }


    /**
     * 停止定时任务
     *
     * @param id 定时任务id
     * @return CommonResult
     * @apiNote -
     * @author jch
     */
    @PostMapping("/stop/{id}")
    public CommonResult stop(@PathVariable
                             @Min(value = 1, message = "id长度最小1")
                             Long id) {
        Boolean flag = scheduledConfig.stop(id);
        if (!flag) return CommonResult.fail();
        return CommonResult.ok();
    }


    /**
     * 立刻执行一次
     *
     * @param id 定时任务id
     * @return CommonResult
     * @apiNote -
     * @author jch
     */
    @PostMapping("/now/{id}")
    public CommonResult now(@PathVariable
                            @Min(value = 1, message = "id长度最小1")
                            Long id) {
        Boolean flag = scheduledConfig.now(id);
        if (!flag) return CommonResult.fail();
        return CommonResult.ok();
    }
}

